package com.app.internationaltravel.service.impl;

import com.app.internationaltravel.config.SystemConfig;
import com.app.internationaltravel.dao.UserDao;
import com.app.internationaltravel.dao.UserDetailDao;
import com.app.internationaltravel.dao.UserGoldDao;
import com.app.internationaltravel.dto.UserAddDto;
import com.app.internationaltravel.dto.UserFindDto;
import com.app.internationaltravel.dto.UserLoginDto;
import com.app.internationaltravel.entity.User;
import com.app.internationaltravel.entity.UserDetail;
import com.app.internationaltravel.entity.UserGold;
import com.app.internationaltravel.service.intf.UserService;
import com.app.internationaltravel.util.*;
import com.app.internationaltravel.vo.R;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;

/**
 * @author 刘豆豆
 * @date 2022/12/12
 */
@Service
public class UserServiceImpl implements UserService {

  @Resource
  private UserDao dao;
  @Resource
  private UserDetailDao detailDao;
  @Resource
  private UserGoldDao goldDao;

/**校验手机号是否可用*/
  @Override
  public R checkPhone(String phone) {
    //1.判断输入的内容不为空
    if (StringUtils.hasLength(phone)){
      //2.正则校验判断手机号是否符合手机号标准
      if (phone.matches(SystemConfig.PHONE_JY)){
        //3.创建查询条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",phone);
        //4.查询数据库
        User user = dao.selectOne(queryWrapper);
        //判断手机号是否存在;
        if (user==null){
          //不存在
          return R.ok("手机号可用");
        }
      }else {
        return R.fail("手机号不符合要求");
      }
    }
    return R.fail("手机号已被注册或");
  }

  /**校验昵称*/
  @Override
  public R checkName(String name) {
    //1.参数校验
    if(StringUtils.hasLength(name)){
      //2.查询数据库并完成校验
      if(dao.selectOne(new QueryWrapper<User>().eq("name",name))==null){
        return R.ok();
      }
    }
    return R.fail("亲，输入的昵称不合规！");
  }

  /**注册*/
  @Override
  @Transactional(rollbackFor = Exception.class)//开启事务保证多个sql语句要么都执行成功要么都失败
  public R register(UserAddDto dto) {
    //判断输入的值不为空
    if (dto != null){
      if(StringUtils.hasLength(dto.getPhone()) && StringUtils.hasLength(dto.getName())){
        //2.校验手机号或用户名 是否存在
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("phone",dto.getPhone()).or().eq("name",dto.getName());
        User user = dao.selectOne(queryWrapper);
        if(user==null){
          user = new User(dto.getName(), dto.getPhone(), PassUtil.aesEnc(SystemConfig.PASS_KEY, dto.getPassword()), SystemConfig.USER_OK, new Date());

          if (JedisUtil.existsSet("auth:checkphones",dto.getPhone())){
               if (dao.insert(user) > 0){
                 //6.注册成功,删除掉，原来记录的验证成功的手机号
                 JedisUtil.delSet("auth:checkphones",dto.getPhone());
                 //7.完成新人有礼，奖励100软件虚拟币
                 detailDao.insert(new UserDetail(user.getId(), 100));
                 //8.记录虚拟币的变动
                  goldDao.insert(new UserGold(user.getId(), 1,100,"新人注册奖励100虚拟币"));
                 return R.ok("注册成功");
               }
             }

        }
      }
    }
    return R.fail("亲，注册失败，请检查！");
  }

  /**
   * 4.登录 账号（手机号或昵称）密码*/
  @Override
  public R loginAccount(UserLoginDto dto) {
    if (dto != null){
      QueryWrapper<User> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("name",dto.getAccount()).or().eq("phone",dto.getAccount());
      User user = dao.selectOne(queryWrapper);
      if (user != null){
          if (user.getPassword().equals(PassUtil.aesEnc(SystemConfig.PASS_KEY,dto.getPassword()))){
            //5.登录成功 令牌：登录成功的标识，可以很简单，也可以很复杂 令牌存储起来，一般还有 有效期
            String token=user.getId()+"";
            JedisUtil.addStr("auth:token:"+user.getPhone(),token,1800);
            //6.返回 记得把令牌返回
            return R.ok(token);
          }
      }
    }
    return R.fail("亲，账号或密码不正确！");
  }

  /**
   * 5.登录 手机号验证码*/
  @Override
  public R loginCode(UserLoginDto dto) {
    if (dto!=null){
      if(StringUtils.hasLength(dto.getAccount())){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone",dto.getAccount());
        User user = dao.selectOne(queryWrapper);
        if (user != null){
          if (JedisUtil.existsKey("auth:login:"+dto.getAccount())){
            //4.比较验证码
            if(JedisUtil.getStr("auth:login:"+dto.getAccount()).equals(dto.getPassword())){
              //5.成功  生成令牌 存储到Redis
              String token=user.getId()+"";

              JedisUtil.addStr("auth:token:"+user.getPhone(),token,1800);

              //6.删除验证码 保证一次性
              JedisUtil.delKeys("auth:login:"+user.getPhone());
              //7.返回 记得把令牌返回
              return R.ok(token);

            }
          }
        }
      }
    }
    return R.fail("亲，账号或验证码不正确！");
  }

  @Override
  public R checkToken(String phone, String token) {
    //1.校验
    if(StringUtils.hasLength(phone)){
      //2.验证是否存在
      if(JedisUtil.existsKey("auth:token:"+phone)){
        //3.在比对 令牌的内容
        if(token.equals(JedisUtil.getStr("auth:token:"+phone))){

          return R.ok();
        }
      }
    }
    return R.fail();

  }

  @Override
  public R all() {
    return R.ok(dao.selectList(null));
  }

  @Override
  public R findPass(UserFindDto dto) {
    //1.校验
    if(dto!=null){
      //2.验证是否存在 验证码
      String key="auth:find:"+dto.getPhone();
      if(JedisUtil.existsKey(key)){

        //3.校验 验证码
        if(JedisUtil.getStr(key).equals(dto.getCode())){

          //4.修改密码
          if(dao.updatePass(PassUtil.aesEnc(SystemConfig.PASS_KEY,dto.getPassword()),dto.getPhone())>0){
            //5.删除验证码
            JedisUtil.delKeys(key);

            return R.ok();
          }
        }
      }
    }
    return R.fail("亲，密码找回失败！请反思！");
  }

  @Override
  public R loginOut(String phone) {
    //1.验证是否存在令牌
    if(JedisUtil.existsKey("auth:token:"+phone)){
      //2.存在令牌 删除
      JedisUtil.delKeys("auth:token:"+phone);
      return R.ok();
    }
    return R.fail();
  }
}
